define(function (require, exports, module) {
    'use strict';
    var $ = require('jquery'),
        _ = require('underscore'),
        Backbone = require('backbone'),
        notify = require('js/utils/notify'),
        models = require('js/apps/preset/models'),
        utils = require('js/utils/tools'),
        uploader = require('js/utils/uploader'),
        common = require('js/apps/preset/common'),
        app = Backbone.history;
    require('jquery-ui');
    require('multiselect');
    require('magnific');
    require('lib/plugins/nestable/jquery.nestable');

    var PresetListView = Backbone.View.extend({
        tagName: "div",
        events: {
            'click a.onClickDelete': 'toDelete',
            'click .add-new': 'createNew',
            'click .clone': 'cloneNew',
            'click #search': 'doSearch'
        },

        initialize: function (options) {
            this.options = options;
            this.collection = new models.PresetCollection();
            this.collection.bind('change reset remove', this.renderWithData, this);
        },
        render: function () {
            this.$el.html("");
            $(window).scrollTop(0);
            return this;
        },
        toDelete: function (e) {
            utils.deleteItem(e, this.collection);
        },
        createNew: function (event) {
            return common.createOrClone(event, '/admin/preset/');
        },
        cloneNew: function (e) {
            return common.createOrClone(e, '/admin/preset/',
                $(e.currentTarget).closest('tr').data('id'));
        },
        doSearch: function () {
            var searched = {},
                options = this.options;
            searched.version = parseInt($('#searchVersion').val());
            searched.device_type = parseInt($('#searchDeviceType').val());
            if (!isNaN(searched.version)) {
                options.version = searched.version;
            }
            options.device_type = searched.device_type;
            utils.saveSearched('preset', searched);
            app.navigate(utils.composeQueryString('#preset/', options), {
                trigger: true
            });
        },
        renderWithData: function () {
            this.$el.html(this.template({
                presets: this.collection.toJSON(),
                searched: utils.getSearched('preset')
            }));
            var that = this;
            utils.getPaginator(that.options, this.collection.total, '#preset/');
            utils.renderTable('main-list', {
                $orderby: that.options.$orderby || 'id',
                sortCallback: function (field) {
                    that.options.$orderby = field;
                    that.options.$page = 1;
                    var newUrl = utils.composeQueryString('#preset/', that.options);
                    app.navigate(newUrl, {
                        trigger: true
                    });
                }
            });
            return this;
        },
        load: function () {
            this.collection.fetch({
                reset: true,
                data: this.options,
                error: function (c, r, o) {
                    notify.notifyResp(r);
                    $('#content').append('<h4 class="text-muted">无数据</h4>');
                },
            });
        }
    });

    exports.List = Backbone.View.extend({
        el: "#content_wrapper",
        template: "preset/PresetList.html",
        initialize: function (options) {
            this.options = options;
        },
        render: function () {
            var view = new PresetListView(this.options);
            view.template = this.template;

            this.$el.empty();
            this.$el.append(view.render().el);
            view.load();

            return this;
        }
    });
    var BannerPanel = Backbone.View.extend({
        tagName: 'li',
        className: 'dd-item',
        template: 'preset/BannerPanel.html',
        events: {
            'click .delete-banner': 'deleteBanner'
        },
        initialize: function (options) {
            // options is bannerIds...
            this.banners = new models.BannerCollection();
            this.bannerIds = options;
            this.collection = new models.BannerCollection();
            this.collection.bind('change reset', this.renderWithData, this);
        },
        load: function () {
            var that = this;
            this.banners.fetch({
                reset: true,
                data: {
                    $size: -1,
                    $orderby: 'title'
                },
                success: function () {
                    var models = [],
                        m = null;
                    _.each(that.bannerIds, function (id) {
                        m = that.banners.get(id);
                        if (m) models.push(m);
                    });
                    that.collection.reset(models);
                }
            });
        },
        render: function () {
            this.$el.html(this.template({
                banners: this.collection.toJSON(),
                allBanners: this.banners.toJSON()
            }));
            return this;
        },
        deleteBanner: function (e) {
            e.preventDefault();
            var id = parseInt($(e.target).data('id'));
            this.collection.remove(id);
            this.renderWithData();
            return false;
        },
        renderWithData: function () {
            this.$el.html(this.template({
                banners: this.collection.toJSON(),
                allBanners: this.banners.toJSON()
            }));
            var that = this;
            utils.multiselect('#inputBanner', true);
            $('#addBanner').magnificPopup({
                items: {
                    src: '#addBannerPanel',
                    type: 'inline'
                },
                midClick: true,
                closeOnBgClick: true,
                callbacks: {
                    beforeOpen: function () {
                        $('#submitAddBanner').off('click').click(function () {
                            var selected = $('#inputBanner').val();
                            $.magnificPopup.close();
                            _.each(selected, function (s) {
                                that.collection.add(that.banners.get(s));
                            });
                            that.renderWithData();
                        });
                    },

                }
            });
            this.$el.find('.image-popup').each(function (i, e) {
                $(e).magnificPopup({
                    type: 'image',
                    closeOnContentClick: true,
                    mainClass: 'mfp-img-mobile',
                    image: {
                        verticalFit: true,
                        titleSrc: function (item) {
                            return '<a href="#preset/banner/' + item.el.data('id') +
                                '/" target="_blank">编辑项目</a>';
                        }
                    }
                })
            });
            this.$el.find('.sortable').each(function (i, e) {
                $(e).sortable();
            });
            $('.dd').nestable('destroy').nestable();
            return this;
        }
    });
    var ShortcutPanel = Backbone.View.extend({
        tagName: 'li',
        className: 'dd-item',
        template: 'preset/ShortcutPanel.html',
        events: {
            'click .delete-shortcut': 'deleteShortcut'
        },
        initialize: function (options) {
            // options is shortcutIds...
            this.shortcuts = new models.ShortcutCollection();
            this.shortcutIds = options;
            this.collection = new models.ShortcutCollection();
            this.collection.bind('change reset', this.renderWithData, this);
        },
        load: function () {
            var that = this;
            this.shortcuts.fetch({
                reset: true,
                data: {
                    $size: -1,
                    $orderby: 'title'
                },
                success: function () {
                    var models = [],
                        m = null;
                    _.each(that.shortcutIds, function (id) {
                        m = that.shortcuts.get(id);
                        if (m) models.push(m);
                    });
                    that.collection.reset(models);
                }
            });
        },
        render: function () {
            this.$el.html(this.template({
                shortcuts: this.collection.toJSON(),
                allShortcuts: this.shortcuts.toJSON()
            }));
            return this;
        },
        deleteShortcut: function (e) {
            e.preventDefault();
            var id = parseInt($(e.target).data('id'));
            this.collection.remove(id);
            this.renderWithData();
            return false;
        },
        renderWithData: function () {
            this.$el.html(this.template({
                shortcuts: this.collection.toJSON(),
                allShortcuts: this.shortcuts.toJSON()
            }));
            var that = this;
            utils.multiselect('#inputShortcut', true);
            $('#addShortcut').magnificPopup({
                items: {
                    src: '#addShortcutPanel',
                    type: 'inline'
                },
                midClick: true,
                closeOnBgClick: true,
                callbacks: {
                    beforeOpen: function () {
                        $('#submitAddShortcut').off('click').click(function () {
                            var selected = $('#inputShortcut').val();
                            $.magnificPopup.close();
                            _.each(selected, function (s) {
                                that.collection.add(that.shortcuts.get(s));
                            });
                            that.renderWithData();
                        });
                    },

                }
            });
            this.$el.find('.image-popup').each(function (i, e) {
                $(e).magnificPopup({
                    type: 'image',
                    closeOnContentClick: true,
                    mainClass: 'mfp-img-mobile',
                    image: {
                        verticalFit: true,
                        titleSrc: function (item) {
                            return '<a href="#preset/shortcut/' + item.el.data('id') +
                                '/" target="_blank">编辑项目</a>';
                        }
                    }
                })
            });
            this.$el.find('.sortable').each(function (i, e) {
                $(e).sortable();
            });
            $('.dd').nestable('destroy').nestable();
            return this;
        }
    });
    var DiscoveryPanel = Backbone.View.extend({
        tagName: 'li',
        className: 'dd-item',
        template: 'preset/DiscoveryPanel.html',
        events: {
            'click .delete-discovery': 'deleteDiscovery'
        },
        initialize: function (options) {
            // options is discoveryIds...
            this.discoverys = new models.DiscoveryCollection();
            this.discoveryIds = options;
            this.collection = new models.DiscoveryCollection();
            this.collection.bind('change reset', this.renderWithData, this);
        },
        load: function () {
            var that = this;
            this.discoverys.fetch({
                reset: true,
                data: {
                    $size: -1,
                    $orderby: 'title'
                },
                success: function () {
                    var models = [],
                        m = null;
                    _.each(that.discoveryIds, function (id) {
                        m = that.discoverys.get(id);
                        if (m) models.push(m);
                    });
                    that.collection.reset(models);
                }
            });
        },
        render: function () {
            this.$el.html(this.template({
                discoverys: this.collection.toJSON(),
                allDiscoverys: this.discoverys.toJSON()
            }));
            return this;
        },
        deleteDiscovery: function (e) {
            e.preventDefault();
            var id = parseInt($(e.target).data('id'));
            this.collection.remove(id);
            this.renderWithData();
            return false;
        },
        renderWithData: function () {
            this.$el.html(this.template({
                discoverys: this.collection.toJSON(),
                allDiscoverys: this.discoverys.toJSON()
            }));
            var that = this;
            utils.multiselect('#inputDiscovery', true);
            $('#addDiscovery').magnificPopup({
                items: {
                    src: '#addDiscoveryPanel',
                    type: 'inline'
                },
                midClick: true,
                closeOnBgClick: true,
                callbacks: {
                    beforeOpen: function () {
                        $('#submitAddDiscovery').off('click').click(function () {
                            var selected = $('#inputDiscovery').val();
                            $.magnificPopup.close();
                            _.each(selected, function (s) {
                                that.collection.add(that.discoverys.get(s));
                            });
                            that.renderWithData();
                        });
                    },

                }
            });
            this.$el.find('.image-popup').each(function (i, e) {
                $(e).magnificPopup({
                    type: 'image',
                    closeOnContentClick: true,
                    mainClass: 'mfp-img-mobile',
                    image: {
                        verticalFit: true,
                        titleSrc: function (item) {
                            return '<a href="#discovery/' + item.el.data('id') +
                                '/" target="_blank">编辑项目</a>';
                        }
                    }
                })
            });
            this.$el.find('.sortable').each(function (i, e) {
                $(e).sortable();
            });
            $('.dd').nestable('destroy').nestable();
            return this;
        }
    });
    var LoadingPanel = Backbone.View.extend({
        tagName: 'li',
        className: 'dd-item',
        template: 'preset/LoadingPanel.html',
        events: {
            'click .delete-loading': 'deleteLoading'
        },
        initialize: function (options) {
            // options is loadingIds...
            this.loadings = new models.LoadingCollection();
            this.loadingIds = options;
            this.collection = new models.LoadingCollection();
            this.collection.bind('change reset', this.renderWithData, this);
        },
        load: function () {
            var that = this;
            this.loadings.fetch({
                reset: true,
                data: {
                    $size: -1,
                    $orderby: 'title'
                },
                success: function () {
                    var models = [],
                        m = null;
                    _.each(that.loadingIds, function (id) {
                        m = that.loadings.get(id);
                        if (m) models.push(m);
                    });
                    that.collection.reset(models);
                }
            });
        },
        render: function () {
            this.$el.html(this.template({
                loadings: this.collection.toJSON(),
                allLoadings: this.loadings.toJSON()
            }));
            return this;
        },
        deleteLoading: function (e) {
            e.preventDefault();
            var id = parseInt($(e.target).data('id'));
            this.collection.remove(id);
            this.renderWithData();
            return false;
        },
        renderWithData: function () {
            this.$el.html(this.template({
                loadings: this.collection.toJSON(),
                allLoadings: this.loadings.toJSON()
            }));
            var that = this;
            utils.multiselect('#inputLoading', true);
            $('#addLoading').magnificPopup({
                items: {
                    src: '#addLoadingPanel',
                    type: 'inline'
                },
                midClick: true,
                closeOnBgClick: true,
                callbacks: {
                    beforeOpen: function () {
                        $('#submitAddLoading').off('click').click(function () {
                            var selected = $('#inputLoading').val();
                            $.magnificPopup.close();
                            _.each(selected, function (s) {
                                that.collection.add(that.loadings.get(s));
                            });
                            that.renderWithData();
                        });
                    },

                }
            });
            this.$el.find('.image-popup').each(function (i, e) {
                $(e).magnificPopup({
                    type: 'image',
                    closeOnContentClick: true,
                    mainClass: 'mfp-img-mobile',
                    image: {
                        verticalFit: true,
                        titleSrc: function (item) {
                            return '<a href="#preset/loading/' + item.el.data('id') +
                                '/" target="_blank">编辑项目</a>';
                        }
                    }
                })
            });
            this.$el.find('.sortable').each(function (i, e) {
                $(e).sortable();
            });
            $('.dd').nestable('destroy').nestable();
            return this;
        }
    });
    var PannelWrapper = Backbone.View.extend({
        events: {
            'change #inputDeviceType': 'checkIOS',
        },
        template: "preset/PannelWrapper.html",
        initialize: function (options) {
            this.info = options.preset;
        },
        render: function () {
            this.$el.html(this.template({
                info: this.info,
            }));
            return this;
        },
        checkIOS: function (e) {
            var val;
            if (e) {
                val = utils.calcDeviceType($(e.target).val());
            } else {
                val = this.info['device_type'];
            }
        }

    });
    var PayPanel = Backbone.View.extend({
        tagName: 'li',
        className: 'dd-item',
        template: 'preset/PayPanel.html',
        events: {
            'click .delete-pay': 'deletePay'
        },
        initialize: function (options) {
            // options is payIds...
            this.pays = new models.PayCollection();
            this.payIds = options;
            this.collection = new models.PayCollection();
            this.collection.bind('change reset', this.renderWithData, this);
        },
        load: function () {
            var that = this;
            this.pays.fetch({
                reset: true,
                data: {
                    $size: -1,
                    $orderby: 'title'
                },
                success: function () {
                    var models = [],
                        m = null;
                    _.each(that.payIds, function (id) {
                        m = that.pays.get(id);
                        if (m) models.push(m);
                    });
                    that.collection.reset(models);
                }
            });
        },
        render: function () {
            this.$el.html(this.template({
                pays: this.collection.toJSON(),
                allPays: this.pays.toJSON()
            }));
            return this;
        },
        deletePay: function (e) {
            e.preventDefault();
            var id = parseInt($(e.target).data('id'));
            this.collection.remove(id);
            this.renderWithData();
            return false;
        },
        renderWithData: function () {
            this.$el.html(this.template({
                pays: this.collection.toJSON(),
                allPays: this.pays.toJSON()
            }));
            var that = this;
            utils.multiselect('#inputPay', true);
            $('#addPay').magnificPopup({
                items: {
                    src: '#addPayPanel',
                    type: 'inline'
                },
                midClick: true,
                closeOnBgClick: true,
                callbacks: {
                    beforeOpen: function () {
                        $('#submitAddPay').off('click').click(function () {
                            var selected = $('#inputPay').val();
                            $.magnificPopup.close();
                            _.each(selected, function (s) {
                                that.collection.add(that.pays.get(s));
                            });
                            that.renderWithData();
                        });
                    },
                }
            });
            this.$el.find('.image-popup').each(function (i, e) {
                $(e).magnificPopup({
                    type: 'image',
                    closeOnContentClick: true,
                    mainClass: 'mfp-img-mobile',
                    image: {
                        verticalFit: true,
                        titleSrc: function (item) {
                            return '<a href="#preset/pay/' + item.el.data('id') +
                                '/" target="_blank">编辑项目</a>';
                        }
                    }
                })
            });
            this.$el.find('.sortable').each(function (i, e) {
                $(e).sortable();
            });
            $('.dd').nestable('destroy').nestable();
            return this;
        }
    });
    var FloatIconPanel = Backbone.View.extend({
        tagName: 'li',
        className: 'dd-item',
        template: 'preset/FloatIconPanel.html',
        events:{
            'click .delete-float_icon': 'deleteFloatIcon'
        },
        initialize: function (options) {
            this.float_icons = new models.FloatIconCollection();
            this.floatIconIds = options;
            this.collection = new models.FloatIconCollection();
            this.collection.bind('change reset', this.renderWithData, this);
        },
        load: function () {
            var that = this;
            this.float_icons.fetch({
                reset: true,
                data: {
                    $size: -1,
                    $orderby: 'title'
                },
                success: function() {
                    var models = [],
                        m = null;
                       _.each(that.floatIconIds, function(id){
                            m = that.float_icons.get(id);
                            if (m) models.push(m);
                       });
                       that.collection.reset(models);
                }
            });
        },
        render: function () {
            this.$el.html(this.template({
                float_icons: this.collection.toJSON(),
                allFloatIcons: this.float_icons.toJSON()
            }));
            return this;
        },
        deleteFloatIcon: function (e) {
            e.preventDefault();
            var id = parseInt($(e.target).data('id'));
            this.collection.remove(id);
            this.renderWithData();
            return false;
        },
        renderWithData: function () {
            this.$el.html(this.template({
                float_icons: this.collection.toJSON(),
                allFloatIcons: this.float_icons.toJSON()
            }));
            var that = this;
            utils.multiselect('#inputFloatIcon', true);
            $('#addFloatIcon').magnificPopup({
                items: {
                    src: '#addFloatIconPanel',
                    type: 'inline'
                },
                midClick: true,
                closeOnBgClick: true,
                callbacks: {
                    beforeOpen: function () {
                        $('#submitAddFloatIcon').off('click').click(function () {
                            var selected = $('#inputFloatIcon').val();
                            $.magnificPopup.close();
                            _.each(selected, function(s) {
                                that.collection.add(that.float_icons.get(s));
                            });
                            that.renderWithData();
                        });
                    }

                }
            });
            this.$el.find('.image-popup').each(function (i, e) {
                $(e).magnificPopup({
                    type: 'image',
                    closeOnContentClick: true,
                    mainClass: 'mfp-img-mobile',
                    image: {
                        verticalFit: true,
                        titleSrc: function (item) {
                            return '<a href="#preset/float_icon/' + item.el.data('id') +
                                '/" target="_blank">编辑项目</a>';
                        }
                    }
                });

            });
            this.$el.find('.sortable').each(function (i, e){
                $(e).sortable();
            });
            $('.dd').nestable('destory').nestable();
            return this;
        }
    });
    exports.Detail = Backbone.View.extend({
        el: "#content_wrapper",
        template: "preset/PresetDetail.html",
        events: {
            'click #save': 'toSaveOrCreate',
            'click #expandAll': 'expandAll',
            'click #collapseAll': 'collapseAll'
        },
        initialize: function (options) {
            this.model = new models.Preset();
            if (options.id) {
                this.model.set('id', options.id);
            }
            this.model.bind('reset change', this.renderWithData, this);
        },
        getInputs: function () {
            var isAllRight = true;
            var _composeJson = function (data, elem) {
                var $this = $(elem);
                if ($this.hasClass('placeholder')) return data;
                if ($this.is('[data-field]')) {
                    var field = $this.data('field');
                    if ($this.is('ol')) { // key
                        if ($this.data('type') == 'dict') {
                            data[field] = {};
                            $this.children().each(function (i, e) {
                                _composeJson(data[field], e);
                            });
                        } else if ($this.data('type') == 'flat') { //flat array
                            var t = [];
                            $this.children().each(function (i, e) {
                                _composeJson(t, e);
                            });
                            data[field] = t;
                            return data;
                        } else { //default is array
                            data[field] = [];
                            $this.children().each(function (i, e) {
                                var t = _composeJson({}, e);
                                if (_.isEmpty(t)) {
                                    return data;
                                }
                                data[field].push(t);
                                return data;
                            });
                        }
                    } else { // value
                        var v = utils.getInput(elem);
                        if (v == $this.data('useless')) return data;
                        if (!$this.is('.placeholder') && !utils.validElement(elem)) {
                            $this.removeClass("state-success").addClass("state-error");
                            isAllRight = false;
                        }
                        if (_.isArray(data)) data.push(v);
                        else data[field] = v;
                        return data;
                    }
                } else if ($this.find('[data-field]')) {
                    $this.children().each(function (i, e) {
                        _composeJson(data, e);
                    });
                    return data;
                }

                return data;
            };
            var attrs = utils.getAllInput('#commAttr');
            attrs.device_type = utils.calcDeviceType(attrs.device_type);
            if (!attrs.max_version) attrs.max_version = null;
            attrs.content = {};
            _composeJson(attrs.content, '#root');
            if (!isAllRight) {
                return null;
            }
            return attrs;
        },
        toSaveOrCreate: function (e) {
            e.preventDefault();
            e.stopImmediatePropagation();
            if (!utils.simpleCheck('#commAttr')) {
                notify.error('错误', '输入错误，请检查');
                return;
            }
            var attrs = this.getInputs();
            if (attrs == null) {
                this.expandAll();
                notify.error('错误', '输入错误，请检查');
                return;
            }
            //FIXME: model randomly rollback for some reason to debug
            var href = location.href.split('/');
            this.model.set('id', parseInt(href[href.length - 2]));

            this.model.save(attrs, {
                patch: true,
                success: function (model) {
                    notify.success('提示', '保存成功！');
                    setTimeout(function () {
                        history.back();
                    }, 500);
                },
                error: function (model, data) {
                    notify.notifyResp(data);
                }
            });
            return false;
        },
        render: function () {
            this.$el.html('');
            $(window).scrollTop(0);
            this.load();
            return this;
        },
        expandAll: function () {
            $('.dd').nestable('expandAll');
        },
        collapseAll: function () {
            $('.dd').nestable('collapseAll');
        },
        renderWithData: function () {
            this.$el.html(this.template({}));
            var info = this.model.toJSON(),
                wrapper = new PannelWrapper({
                    preset: this.model.toJSON()
                });
            $('#content').append(wrapper.render().el);
            wrapper.checkIOS();

            var shortcut = new ShortcutPanel(info.content.shortcut || []);
            $('#root').append(shortcut.render().el);
            shortcut.load();
            var banner = new BannerPanel(info.content.banner || []);
            $('#root').append(banner.render().el);
            banner.load();
            var discovery = new DiscoveryPanel(info.content.discovery || []);
            $('#root').append(discovery.render().el);
            discovery.load();
            var loading = new LoadingPanel(info.content.pages || []);
            $('#root').append(loading.render().el);
            loading.load();
            var pay = new PayPanel(info.content.pay || []);
            $('#root').append(pay.render().el);
            pay.load();
            var float_icon = new FloatIconPanel(info.content.float_icon || []);
            $('#root').append(float_icon.render().el);
            float_icon.load();
            utils.multiselect('.multiselect');

            return this;
        },
        load: function () {
            var that = this;
            if (this.model.get('id')) {
                this.model.fetch({
                    reset: true,
                    error: function (data) {
                        notify.notifyResp(data);
                    }
                })
            } else {
                this.renderWithData();
            }
        }
    });

    exports.Pannels = [ ShortcutPanel, BannerPanel,DiscoveryPanel,LoadingPanel, PannelWrapper,PayPanel, FloatIconPanel];
});
